/* eslint-disable radix */
/* eslint-disable no-use-before-define */
/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { computed, defineComponent, SetupContext, ref, withModifiers, watch, onBeforeUnmount } from 'vue';
import { RateProps, rateProps } from './rate.props';
import './rate.css';

export default defineComponent({
    name: 'FRate',
    props: rateProps,
    emits: ['selectedValue'] as (string[] & ThisType<void>) | undefined,
    setup(props: RateProps, context: SetupContext) {
        /** 星星大小 */
        const size = ref(props.size);
        /** 启用半颗星模式 */
        const enableHalf = ref(props.enableHalf);
        /** 启用再次点击后清除 */
        const enableClear = ref(props.enableClear);
        /** 只读 */
        const disabled = ref(props.disabled);
        /** 分制 */
        const pointSystem = ref(props.pointSystem);
        /** 星星亮色 */
        const lightColor = ref(props.lightColor);
        /** 星星暗色（底色） */
        const darkColor = ref(props.darkColor);
        /** 图案样式 */
        const iconClass = ref(props.iconClass);
        /** 星星个数 */
        const numOfStar = ref(props.numOfStar);
        /** 禁用单个星星的文字提示 */
        const toolTipDisabled = ref(props.toolTipDisabled);
        /** 默认的满意度文案 */
        const toolTipContents = ref(props.toolTipContents);
        /** 启用评分 */
        const enableScore = ref(props.enableScore);
        /** 启用满意度 */
        const enableSatisfaction = ref(props.enableSatisfaction);
        /** 一颗星宽度 */
        let oneStarWidth: number;
        /** 亮色区域虚拟宽度 */
        const lightStarAreaWidth = ref(1);
        /** 界面中亮色区域真实宽度 */
        let realWidth = 0;
        /** 虚拟分数 */
        const score = ref(0);
        /** 最终分数 */
        const realScore = ref(0);
        /** 比率 */
        let rate = 1;
        /** 切换的满意度 */
        let satisfaction: any;
        /** 最终显示的满意度 */
        let realSatisfaction: any;
        /** 配置 */
        let config: any[];
        /** 星星之间的间距 */
        const distance = 4;

        function initOperation() {
            switch (size.value) {
            case 'small':
                oneStarWidth = 14;
                break;
            case 'middle':
                oneStarWidth = 16;
                break;
            case 'large':
                oneStarWidth = 18;
                break;
            case 'extraLarge':
                oneStarWidth = 24;
                break;
            }
            updateStarConfig();
            if (numOfStar.value) {
                rate = pointSystem.value / numOfStar.value;
            }
            if (realScore.value) {
                scoreChanged();
            }
        }
        initOperation();

        /** 更新Config */
        function updateStarConfig() {
            const inputNum = numOfStar.value;
            config = [];
            for (let i = 1; i <= inputNum; i++) {
                config.push({ id: i });
            }
        }
        /**
         * 是否是目标元素
         * @param element
         */
        function isTargetElement(element: any) {
            if (element.className.indexOf('f-icon') !== -1) {
                return true;
            }
            return false;
        }
        function scoreChanged() {
            let starId;
            if (enableHalf.value) {
                starId = Math.ceil(realScore.value / rate);
            } else {
                starId = realScore.value;
            }
            realWidth = (oneStarWidth * realScore.value + Math.floor(realScore.value) * distance) / rate;
            satisfaction = toolTipContents.value[starId - 1];
        }
        /**
         *  再次点击取消选中
         */
        function clear() {
            if (lightStarAreaWidth.value === realWidth && enableClear && realWidth !== 0) {
                realWidth = 0;
                realScore.value = 0;
                realSatisfaction = null;
                // 待改：响应式
                lightStarAreaWidth.value = 0;
                score.value = 0;
                context.emit('selectedValue', realScore.value);
                return true;
            }
            return false;
        }
        // watch(lightStarAreaWidth, (i: any) => {
        //     console.log(i);
        // });
        /**
         *
         * @param event 事件
         * @param id 当前星星的id
         * @param token 是否点击事件触发
         */
        function operateStar(event: any, id: any, token: boolean) {
            if (event.movementX || event.movementY) {
                // 禁用
                if (disabled.value) {
                    return;
                }
                // 满意度文案
                if (enableSatisfaction.value) {
                    satisfaction = toolTipContents.value[id - 1];
                }
                // 如果滑动的距离小于一颗星星一半的距离（或者超过）
                if (event.offsetX < oneStarWidth / 2 && enableHalf.value === true) {
                    lightStarAreaWidth.value = oneStarWidth * id - oneStarWidth / 2 + distance * (id - 1);
                    score.value = rate * id - rate / 2;
                } else {
                    lightStarAreaWidth.value = oneStarWidth * id + distance * (id - 1);
                    score.value = rate * id;
                }
            }
            if (token === true) {
                if (clear()) {
                    return;
                }
                realScore.value = score.value;
                realWidth = lightStarAreaWidth.value;
                realSatisfaction = satisfaction;
                context.emit('selectedValue', realScore.value);
            }
        }

        function operateStarFunction(event: any, isclick: boolean): any {
            if (!isTargetElement(event.target)) {
                return;
            }
            if (event.target) {
                const id = parseInt(event.target?.id);
                operateStar(event, id, isclick);
            }
        }
        const rateScore = computed(() => {
            return score.value ? score.value + '分' : realScore.value + '分';
        });

        const lightAreaStyle = computed(() => {
            const styleObject = {
                width: (lightStarAreaWidth.value || realWidth) + 'px'
            } as Record<string, any>;
            return styleObject;
        });
        return () => {
            return (
                <div
                    class="farris-star-rating"
                    onMouseover={withModifiers((payload: MouseEvent) => operateStarFunction(payload, false), ['prevent'])}
                    onMousemove={withModifiers((payload: MouseEvent) => operateStarFunction(payload, false), ['prevent'])}
                    onMouseout={withModifiers((payload: MouseEvent) => operateStarFunction(payload, false), ['prevent'])}
                    onClick={withModifiers((payload: MouseEvent) => operateStarFunction(payload, true), ['prevent'])}>
                    <div class="star-light-area" style={lightAreaStyle.value}>
                        {config.map((item: any) => (
                            <span
                                class={[
                                    'f-icon default-light-color ',
                                    iconClass.value,
                                    { 'f-star-sm': size.value === 'small' },
                                    { 'f-star-md': size.value === 'middle' },
                                    { 'f-star-lg': size.value === 'large' },
                                    { 'f-star-exlarge': size.value === 'extraLarge' },
                                    { disabled: toolTipDisabled.value }
                                ]}
                                id={item.id}
                                style={{ color: lightColor.value }}></span>
                        ))}
                    </div>

                    <div
                        class={[
                            'star-dark-area',
                            { small: size.value === 'small' },
                            { middle: size.value === 'middle' },
                            { large: size.value === 'large' }
                        ]}>
                        {config.map((item: any) => (
                            <span
                                class={[
                                    'f-icon default-dark-color',
                                    iconClass.value,
                                    { 'f-star-sm': size.value === 'small' },
                                    { 'f-star-md': size.value === 'middle' },
                                    { 'f-star-lg': size.value === 'large' },
                                    { 'f-star-exlarge': size.value === 'extraLarge' }
                                ]}
                                id={item.id}
                                style={{ color: darkColor.value }}></span>
                        ))}
                    </div>
                    <div
                        class={[
                            'f-utils-fill',
                            { 'font-small': size.value === 'small' },
                            { 'font-middle': size.value === 'middle' },
                            { 'font-large': size.value === 'large' },
                            { 'font-exlarge': size.value === 'extraLarge' }
                        ]}>
                        {enableScore.value && <span> {rateScore.value} </span>}
                        {enableSatisfaction.value && (realSatisfaction || satisfaction) && <span> {satisfaction || realSatisfaction}</span>}
                    </div>
                </div>
            );
        };
    }
});
